#pragma once

#include <iostream>
#include <string>
#include<jsoncpp/json/json.h> 

// #define Myself 1

const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

//封装报头
std::string Encode(const std::string& content)
{   
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;

    return package;
}

//"len"\n"x op y"\n
bool Decode(std::string& package, std::string* content)
{
    size_t pos = package.find(protocol_sep);
    if(pos == std::string::npos)
        return false;
    std::string len_str = package.substr(0,pos);
    size_t len = std::stoi(len_str);
    //package = len_str + content_str + 2 //2表示两个\n

    size_t total_len = len + len_str.size() + 2;
    if(total_len > package.size())
        return false;

    *content = package.substr(pos + 1, len);

    package.erase(0, total_len);
    return true;

}

class Request
{
public:
    Request(int data1, int data2, char oper):x(data1), y(data2), op(oper)
    {}  
    Request()
    {}

    bool Serialize(std::string* out)
    {
#ifdef Myself
        //构建报文的有效载荷
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += std::to_string(y);

        *out = s;
        return true;
#else
        Json::Value root;
        root["x"] = x;
        root["y"] = y;
        root["op"] = op;
        Json::FastWriter w;
        *out = w.write(root);
        return true;
#endif
    }


    bool Deserialize(const std::string &in)
    {
#ifdef Myself
        //  提取 x
        size_t left = in.find(blank_space_sep);
        if(left == std::string::npos)
            return false;
        std::string part_x = in.substr(0,left);

        //  提取 y
        size_t right = in.rfind(blank_space_sep);
        if(right == std::string::npos)
            return false;
        std::string part_y = in.substr(right + 1);

        if(left + 2 != right) //op不合法
            return false;

        x = std::stoi(part_x);
        y = std::stoi(part_y);
        op = in[left + 1];
 
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);
        x = root["x"].asInt();
        y = root["y"].asInt();
        op = root["op"].asInt();
        return true;
        
#endif
    }
    void debugPrint()
    {
        std::cout << "新请求构建成功： " << x << op << y << std::endl;
    }
public:
    //x op y
    int x;
    int y;
    char op;// + - * /
};

class Response
{
public:
    Response(int res, int code):result(res), status(code)
    {}
    Response()
    {}

    bool Serialize(std::string* out)
    {
#ifdef Myself

        // "len""\n" "result status"
        //构建报文有效载荷
        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(status);

        *out = s;
        return true;
#else
        Json::Value root;
        root["result"] = result;
        root["status"] = status;
        Json::FastWriter w;
        *out = w.write(root);
        return true;
#endif
    }

    bool Deserialize(const std::string &in)// "result status"
    {
#ifdef Myself

        size_t left = in.find(blank_space_sep);
        if(left == std::string::npos)
            return false;
        std::string part_res = in.substr(0,left);
        std::string part_sta = in.substr(left+1);

        result = std::stoi(part_res);
        status = std::stoi(part_sta);

        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);
        result = root["result"].asInt();
        status = root["status"].asInt();
        return true;
#endif
    }
    void debugPrint()
    {
        std::cout << "结果响应完成 ： result:" << result << " status:" << status << std::endl;
    }
public:
    int result; //运算结果
    int status; //运算结果是否可靠,0表示可靠，非0表示错误
};